<svelte:window on:click="set({open:false})" />

<div on:click="event.stopPropagation()" class="control-group vis-option-group vis-option-type-select">
    <div class="dropdown {icon?'icon':''} {!open && selection ? 'selection' : ''}" on:click="onClick(event)">
        <input
            type="search"
            ref:searchInput
            placeholder="{open ? placeholder : selection||placeholder}"
            bind:value="query"
            on:keypress="keyup(event)"
            on:input="search(query)"
        />

        {#if icon}
        <i class="icon {icon}"></i>
        {/if}

        <div class="btn-wrap">
            <slot name="button">
                <button class="btn btn-small btn-primary" on:click="set({open:true})">
                    <span class="caret"></span>
                </button>
            </slot>
        </div>

        {#if open && matches.length}
        <ul ref:dropdown class="dropdown-results">
            {#each matches as item,i}

            <li class="{i==selectedIndex?'selected':''}" style="{item.style||''}" on:click="select(item, event)">
                <!-- <i class="fa fa-plus-circle"></i> -->
                {@html item.display || item.title}
            </li>

            {/each}
        </ul>
        {/if}
    </div>
</div>

<script>
    export default {
        data() {
            return {
                selection: '',
                query: '',
                icon: false,
                placeholder: '',
                filter: 'indexOf',
                selectedItem: undefined,
                selectedIndex: undefined,
                searching: false,
                open: false,
                items: [] // items look like this {id: "foo", title: "", "display": "..."}
            };
        },
        computed: {
            matches({ query, items, filter }) {
                if (!filter) return items;
                if (!query) return items;
                // check if items is an array
                if (!items || !items.filter) return [];
                return items.filter(item => {
                    return (item.search || item.title).toLowerCase().indexOf(query.toLowerCase()) > -1;
                });
            }
        },
        methods: {
            focus() {
                this.refs.searchInput.focus();
            },

            blur() {
                this.refs.searchInput.blur();
            },

            onClick(event) {
                this.set({ open: true });
                this.fire('focus', event);
            },

            search(query) {
                this.set({ open: true });
                // we're firing the "search" event so that the
                // parent component can update the "items" list
                this.fire('search', { query });
            },

            select(item, event) {
                this.set({
                    selectedItem: item,
                    query: item.title,
                    open: false
                });
                if (event) event.stopPropagation();
                this.fire('select', { item });
            },

            keyup(event) {
                if (!event) return;
                if (event.keyCode === 13) {
                    // RETURN key
                    const { selectedItem } = this.get();
                    this.select(selectedItem);
                }
                if (event.keyCode === 38 || event.keyCode === 40) {
                    // ARROW UP/DOWN
                    let { selectedIndex, matches } = this.get();
                    if (isNaN(selectedIndex)) selectedIndex = -1;
                    const len = matches.length || 0;
                    if (event.keyCode === 38) {
                        selectedIndex = (selectedIndex - 1 + len) % len;
                    }
                    if (event.keyCode === 40) {
                        selectedIndex = (selectedIndex + 1) % len;
                    }

                    this.set({
                        selectedIndex,
                        selectedItem: matches[selectedIndex]
                    });
                }
                if (event.keyCode === 27) {
                    // ESCAPE
                    this.set({ open: false });
                    this.blur();
                }
            }
        },
        // eslint-disable-next-line
        onupdate({ changed, current }) {
            if (changed.selectedIndex && this.refs.dropdown) {
                const dd = this.refs.dropdown;
                const i = current.selectedIndex;
                const liBox = dd.children[i].getBoundingClientRect();
                const ulBox = dd.getBoundingClientRect();
                if (liBox.y + liBox.height - ulBox.y > ulBox.height) {
                    // li is out of bottom view
                    dd.scrollBy(0, liBox.y + liBox.height - ulBox.y - ulBox.height + 5);
                } else if (liBox.y - ulBox.y < 0) {
                    // li is out of top view
                    dd.scrollBy(0, liBox.y - ulBox.y - 5);
                }
            }
        }
    };
</script>

<style lang="less">
    .dropdown {
        display: flex;
        flex-wrap: wrap;
        position: relative;

        &.icon {
            input {
                padding-left: 30px;
            }
            .icon {
                position: absolute;
                left: 7px;
                top: 6px;
                &.im {
                    top: 8px;
                }
                color: #ccc;
                font-size: 17px;
            }
        }

        &.selection {
            @selection_color: #222;
            @selection_weight: 300;
            input::-webkit-input-placeholder {
                color: @selection_color;
                font-weight: @selection_weight;
                opacity: 1;
            }
            input::-moz-placeholder {
                color: @selection_color;
                font-weight: @selection_weight;
                opacity: 1;
            }
            input:-ms-input-placeholder {
                color: @selection_color;
                font-weight: @selection_weight;
                opacity: 1;
            }
            input:-moz-input-placeholder {
                color: @selection_color;
                font-weight: @selection_weight;
                opacity: 1;
            }
        }
    }

    .dropdown-results li.selected {
        background: #18a1cd33;
    }
    .control-group {
    }

    input {
        margin-bottom: 0px;
        /*      width: 250px;*/
        /*width: calc(100% - 73px);*/
        flex-grow: 4;
    }

    .btn-wrap {
        flex-grow: 1;
    }

    .btn-small {
        max-width: 60px;
        padding: 4px 10px;
        border-radius: 0px 3px 3px 0px !important;
        margin-left: -4px;
        border-left: none;
    }

    .dropdown-results {
        max-height: 150px;
        overflow: auto;
        margin: 0px;
        /*width: 262px;*/
        width: ~'calc(100% - 21px)';
        background-color: white;
        border: 1px solid #cccccc;
        margin-top: 0px;
        border-top: 0;
        box-shadow: 2px 2px 2px #0001;
        /*width: 94%;*/
    }

    .dropdown-results li {
        color: black;
        padding: 12px 16px;
        text-decoration: none;
        display: block;
        padding: 5px 6px;
    }

    .dropdown-results li:hover {
        background-color: #18a1cd33;
        cursor: pointer;
    }
</style>
